package com.mxpio.erp.plm.job;

import com.mxpio.erp.common.enums.PlmEnums;
import com.mxpio.erp.common.plm.entity.ProjectInfo;
import com.mxpio.erp.common.plm.service.ProjectInfoService;
import com.mxpioframework.jpa.query.Criteria;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List;

@Slf4j
@Component
public class ProjectInfoOverdueJob implements Job {

    @Autowired
    private ProjectInfoService projectInfoService;
    /**
     * 对项目，进行是否逾期 和 逾期天数的计算
     * 逻辑：当前日期大于计划完工时间-逾期
     * 每天计算一次
     */
    @Override
    @Transactional
    public void execute(JobExecutionContext context) throws JobExecutionException {
        log.info(" --- 计算项目逾期天数开始 --- ");
        Criteria criteria = Criteria.create();
        List<ProjectInfo> list = projectInfoService.list(ProjectInfo.class, criteria);
        for (ProjectInfo projectInfo : list) {
            //对完成的逾期项目的天数，只计算到实际结束那天
            //没有逾期的计算，是否逾期，和逾期天数
            if (StringUtils.equals(projectInfo.getStatus(), "1")){
            //判断项目是否逾期
                //判断是否完成
                if (StringUtils.equals(projectInfo.getProStatus(), PlmEnums.ProStatus.FINISH.getCode())){
                    Date actualEndTime = projectInfo.getActualEndTime();
                    //因为历史原因，实际结束时间可能为空
                    if (projectInfo.getActualEndTime() == null) {
                        actualEndTime = new Date();
                    }
//                    Date actualEndTime = projectInfo.getActualEndTime();
                    LocalDate planActualEndTime = actualEndTime.toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalDate();
                    Date planEndTime = projectInfo.getPlanEndTime();
                    LocalDate planEndLocalDate = planEndTime.toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalDate();
                    if (planActualEndTime.isAfter(planEndLocalDate)) {
                        projectInfo.setStatus("0");//当计划时间超过当前时间时，判断为当前项目延期
                        long daysBetween = ChronoUnit.DAYS.between(planEndLocalDate, planActualEndTime);
                        if (daysBetween < 0) {
                            daysBetween = Math.abs(daysBetween);
                        }
                        projectInfo.setOverdueDay(daysBetween);//逾期天数
                    }
                    projectInfoService.update(projectInfo);
                }else {
                    //未完成时
                    LocalDate currentDate = LocalDate.now(); //获取当前时间
                    Date planEndTime = projectInfo.getPlanEndTime();
                    LocalDate planEndLocalDate = planEndTime.toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalDate();
                    if (currentDate.isAfter(planEndLocalDate)) {
                        projectInfo.setStatus("0");//当计划时间超过当前时间时，判断为当前项目延期
                        long daysBetween = ChronoUnit.DAYS.between(planEndLocalDate, currentDate);
                        if (daysBetween < 0) {
                            daysBetween = Math.abs(daysBetween);
                        }
                        projectInfo.setOverdueDay(daysBetween);//逾期天数
                    }
                    projectInfoService.update(projectInfo);
                }

            }else if (StringUtils.equals(projectInfo.getStatus(), "0")){
                //已经逾期的计算 逾期天数，
                if (!StringUtils.equals(projectInfo.getProStatus(), PlmEnums.ProStatus.FINISH.getCode())){
                    //未完成时
                    LocalDate currentDate = LocalDate.now(); //获取当前时间
                    Date planEndTime = projectInfo.getPlanEndTime();
                    LocalDate planEndLocalDate = planEndTime.toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalDate();
                    if (currentDate.isAfter(planEndLocalDate)) {
                        projectInfo.setStatus("0");//当计划时间超过当前时间时，判断为当前项目延期
                        long daysBetween = ChronoUnit.DAYS.between(planEndLocalDate, currentDate);
                        if (daysBetween < 0) {
                            daysBetween = Math.abs(daysBetween);
                        }
                        projectInfo.setOverdueDay(daysBetween);//逾期天数
                    }
                    projectInfoService.update(projectInfo);
                }else {
                    //已完成时
                    Date actualEndTime = projectInfo.getActualEndTime();
                    //因为历史原因，实际结束时间可能为空
                    if (projectInfo.getActualEndTime() == null) {
                        actualEndTime = new Date();
                    }
//                    Date actualEndTime = projectInfo.getActualEndTime();
                    LocalDate planActualEndTime = actualEndTime.toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalDate();
                    Date planEndTime = projectInfo.getPlanEndTime();
                    LocalDate planEndLocalDate = planEndTime.toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalDate();
                    if (planActualEndTime.isAfter(planEndLocalDate)) {
                        projectInfo.setStatus("0");//当计划时间超过当前时间时，判断为当前项目延期
                        long daysBetween = ChronoUnit.DAYS.between(planEndLocalDate, planActualEndTime);
                        if (daysBetween < 0) {
                            daysBetween = Math.abs(daysBetween);
                        }
                        projectInfo.setOverdueDay(daysBetween);//逾期天数
                    }
                    projectInfoService.update(projectInfo);
                }

            }
//            projectInfoService.update(projectInfo);
        }
        log.info(" --- 计算项目逾期天数结束 --- ");
    }
}
